<?php
namespace Tbf\Bundle\DatabaseBundle\ListQuery;
use Doctrine\ORM\QueryBuilder;
use Tbf\Bundle\DatabaseBundle\Exception\DatabaseException;
use Tbf\Bundle\DatabaseBundle\ListQuery\ConditionalExpress\ConditionalExpressInterface;

class DoctrineOrmQueryBuilderAdapter
{
    protected $lq;
    protected $place_holder_num;
    public function __construct(ListQuery $lq)
    {
        $this->lq = $lq;
    }
    public function loadCountQuery(QueryBuilder $qb)
    {
        $this->loadSelectQuery($qb);
        $qb->setMaxResults(null);
        $qb->setFirstResult(null);
        $qb->select('count(DISTINCT '.$this->getDefaultAlias($qb).')');

        return $qb;
    }
    public function loadSelectQuery(QueryBuilder $qb)
    {
        //page
        if ($this->lq->getIsPageResult()) {
            $qb->setFirstResult($this->lq->getPageSize()*($this->lq->getPage()-1));
            $qb->setMaxResults($this->lq->getPageSize());
        }
        //order
        foreach ($this->lq->getOrder() as $order) {
            $field = $order->getField();
            $field = $this->handleFieldName($qb,$field);
            $qb->addOrderBy($field,$order->getDirection());
        }

        //where
        $this->handleWhere($qb);

        return $qb;
    }
    protected function handleWhere(QueryBuilder $qb)
    {
        $where = $this->lq->getWhere();
        if (empty($where)) {
            return;
        }
        if (!$where instanceof ConditionalExpressInterface) {
            throw new DatabaseException('do not understand where object :'.get_class($where));
        }
        $where->filterOrmQueryBuilder($qb);
    }
    protected function handleFieldName(QueryBuilder $qb,$field_name)
    {
        if (strpos($field_name,'.')===false) {
            $field_name = $this->getDefaultAlias($qb).'.'.$field_name;
        }

        return $field_name;
    }
    protected function getDefaultAlias(QueryBuilder $qb)
    {
        if ($this->lq->getTableAlias()){
            return $this->lq->getTableAlias();
        }
        $aliases = $qb->getRootAliases();

        return $aliases[0];
    }
    protected function placeHolderValue(QueryBuilder $qb,$value)
    {
        $this->place_holder_num +=1;
        $place_holder_name = 'holder_'.$this->place_holder_num;
        $qb->setParameter($place_holder_name,$value);

        return ':'.$place_holder_name;
    }
}
